#include "console.h"
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include "kern.h"
#include "command.h"
#include "init.h"
#if defined(_WIN32)
#include <conio.h>
#elif defined(__unix)
#include <termios.h>
#endif

#define CONSOLE_TASK_PERIOD 5
static task_t console_task = 0;

static char input_line[CONSOLE_LINE_MAX] = {0};
static int base = 0;
static int end = 0;

#if defined(__unix)
static int kbhit(void)
{
    struct termios oldt, newt;
    int ch;
    int oldf;
    tcgetattr(STDIN_FILENO, &oldt);
    newt = oldt;
    // newt.c_lflag &= ~ICANON;
    // newt.c_lflag |= ICANON; // Enable canonical mode
    // newt.c_lflag &= ~ECHO; // Cancel echo
    tcsetattr(STDIN_FILENO, TCSANOW, &newt);
    oldf = fcntl(STDIN_FILENO, F_GETFL, 0);
    fcntl(STDIN_FILENO, F_SETFL, oldf | O_NONBLOCK);
    ch = getchar();
    tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
    fcntl(STDIN_FILENO, F_SETFL, oldf);
    if (ch != EOF)
    {
        ungetc(ch, stdin);
        return 0;
    }
    return 1;
}
#endif

static int delete_input_string(unsigned char num)
{
    unsigned char i = 0;
    for (i = 0; i < num; i++) putchar('\b');
    for (i = 0; i < num; i++) putchar(' ');
    for (i = 0; i < num; i++) putchar('\b');
}

static int into(int argc, char *argv[])
{
    int len = 0;
    if (base != 0) return 0;
    if (argc < 2) return 0;
    len = strlen(argv[1]);
    memcpy(input_line, argv[1], len);
    input_line[len++] = ' ';
    base = len;
    return 1;
}

static void console_main(void)
{
    int c;
    if (!kbhit())
    {
        c = getchar();
#if CONSOLE_DEBUG == 1
        printf("key = %d\r\n", c);
#else 
        switch (c) 
        {
        case 10: // line
        case 13: // return
        {
            if (end != 0) printf("\r\n");
            input_line[end] = 0;
            // printf("input: %s\r\n", input_line);
            command(input_line);
            input_line[base] = 0;
            end = base;
            printf("%s>> ", input_line);
        }break;
        case 8: // backspace
        {
            if (end > base)
            {
                input_line[--end] = 0;
                delete_input_string(1);
            }
        }break;
        case 9: // tab
        {
            
        }break;
        case 27: // esc
        {
            base = 0;
            input_line[0] = 0;
        }break;
        case 68: // left
        {
            
        }break;
        default:
        {
            input_line[end++] = c;
        }break;
        }
#endif
    }
}

void console_init(void) 
{
    /* Create task */
    console_task = task_create(CONSOLE_TASK_PERIOD, console_main);
    if (!console_task) return;

    printf("console init! task<%d>!\r\n", console_task);

    /* Export into command */
    command_export("into", into);
}
init_export_app(console_init);
